#include<iostream>
#include<vector>
#include<cstdlib>
#include<string>
#include<cassert>
#include<pthread.h>
#include<unistd.h>

using namespace std;

//当成结构体使用
class ThreadData
{
public:
    int number;
    pthread_t tid;
    char namebuffer[64];
};

class ThreadReturn
{
public:
   int exit_code;
   int exit_result;
};


void* start_routine(void* args)
{
    sleep(1);
    ThreadData* td = static_cast<ThreadData*>(args); //安全的进行强制类型转化
    int cnt = 10;
    while(cnt)
    {
        //cout << "cnt: " << (int)cnt << " &cnt " << &cnt << endl; // bug?暂时没法解释
        cout <<  (int)cnt <<  &cnt  << endl;
        cnt--;
        //cout << "new thread create success, name: " << td->namebuffer << " cnt: " << cnt-- << endl;
        sleep(1);
     
    }

    ThreadReturn* tr = new ThreadReturn();
    tr->exit_code = 1;
    tr->exit_result = 106;

    //ThreadReturn tr; // 不能这么写，这是在栈上开辟的空间；虽然可以返回，但是这样栈帧空间会被释放，就拿不出来这个值了。
    return (void*)tr; // 右值
}


int main()
{
    //1. 我们想创建一批线程
    vector<ThreadData*> threads;
#define NUM 10
    for(int i=1; i<=NUM; i++)
    {
        ThreadData* td = new ThreadData();
        td->number = i;
        //char namebuffer[64];
        snprintf(td->namebuffer, sizeof(td->namebuffer),"%s:%d", "thread", i);
        pthread_create(&td->tid, nullptr, start_routine, td);
        threads.push_back(td);
        //pthread_create(&tid, nullptr, start_routine, (void*)namebuffer);
        //sleep(1);
    }

    for(auto& iter : threads)
    {
        std::cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " success" << endl;
    }

    //线程是可以被cancel取消的！注意：线程要被取消，前提是这个线程已经跑起来了。
    //线程如果是被取消的，退出码：-1
    //PTHEARD_CANCELED
    sleep(5);
    // for(int i=0; i<threads.size()/2; i++)
    // {
    //     pthread_cancel(threads[i]->tid);
    //     cout << "pthread_cancel : " << threads[i]->namebuffer << "success" << endl;
    // }

    for(auto& iter : threads)
    {
        void* ret = nullptr; //注意：是void* 哦
        //ThreadReturn *ret = nullptr;

        //？ ： 为什么没有见到，线程退出的时候，对应的退出信号？线程出异常收到信号，整个进程都会退出！
        //pthread_join: 默认就会认为函数调用成功！不考虑异常问题，异常问题是你进程该考虑的问题，而不是线程！
        int n = pthread_join(iter->tid, (void**)&ret);
        //int n = pthread_join(iter->tid, nullptr);
        assert(n == 0);
        cout << "join : " << iter->namebuffer <<" success, exit_code: " << (long long)ret << endl;
        delete iter;//在外部统一申请，统一释放
    }

    cout << "man thread quit " << endl;
    return 0;
}